using System;
using System.Collections.Generic;
using System.Text;
using MeetingRoom.Allocation;
using MeetingRoom.Domain;
using MeetingRoom.Data;
using MeetingRoom.Service;
using NUnit.Framework;
using NMock;

namespace MeetingRoom.UnitTest
{
    [TestFixture]
    public class MeetingRoomAllocatorTest
    {
        protected IMock getUpcomingSchedulesMockControl = null;

        protected IMock getMeetingRoomByMeetingRoomTypeMockControl = null;

        protected IMock updateScheduleMockControl = null;

        protected IMock messagingServiceMockControl = null;

        protected IGetUpcommingSchedules getUpcomingSchedulesMock = null;

        protected IGetMeetingRoomsByMeetingRoomType getMeetingRoomByMeetingRoomTypeMock = null;

        protected IUpdateSchedule updateScheduleMock = null;

        protected IMessagingService messagingServiceMock = null;

        [Test]
        public void TestAllocate()
        {
            int minutes = 100;

            this.getUpcomingSchedulesMockControl = new DynamicMock(
                typeof(IGetUpcommingSchedules));
            this.getMeetingRoomByMeetingRoomTypeMockControl = new DynamicMock(
                typeof(IGetMeetingRoomsByMeetingRoomType));
            this.updateScheduleMockControl = new DynamicMock(
                typeof(IUpdateSchedule));
            this.messagingServiceMockControl = new DynamicMock(
                typeof(IMessagingService));

            this.updateScheduleMock = (IUpdateSchedule)
                this.updateScheduleMockControl.MockInstance;
            this.getUpcomingSchedulesMock = (IGetUpcommingSchedules)
                this.getUpcomingSchedulesMockControl.MockInstance;
            this.getMeetingRoomByMeetingRoomTypeMock = (IGetMeetingRoomsByMeetingRoomType)
                this.getMeetingRoomByMeetingRoomTypeMockControl.MockInstance;
            this.messagingServiceMock = (IMessagingService)
                this.messagingServiceMockControl.MockInstance;

            List<MeetingRoom.Domain.MeetingRoom> meetingRooms1
                = new List<MeetingRoom.Domain.MeetingRoom>();
            List<MeetingRoom.Domain.MeetingRoom> meetingRooms2
                = new List<MeetingRoom.Domain.MeetingRoom>();

            List<Schedule> schedules = new List<Schedule>();

            MeetingRoom.Domain.MeetingRoomType meetingRoomType1 = new MeetingRoomType();
            meetingRoomType1.Id = 1;
            meetingRoomType1.Size = 10;

            MeetingRoomType meetingRoomType2 = new MeetingRoomType();
            meetingRoomType2.Id = 2;
            meetingRoomType2.Size = 20;

            MeetingRoom.Domain.MeetingRoom meetingRoom1 = new MeetingRoom.Domain.MeetingRoom();
            meetingRoom1.Name = "Accenture";
            meetingRoom1.MeetingRoomType = meetingRoomType1;
            meetingRooms1.Add(meetingRoom1);

            MeetingRoom.Domain.MeetingRoom meetingRoom2 = new MeetingRoom.Domain.MeetingRoom();
            meetingRoom2.Name = "Prudential";
            meetingRoom2.MeetingRoomType = meetingRoomType2;
            meetingRooms2.Add(meetingRoom2);

            Schedule schedule1 = new Schedule();
            schedule1.Name = "Schedule 1";
            schedule1.MeetingRoomType = meetingRoomType1;
            schedule1.Duration = new Duration(new DateTime(), new DateTime());
            schedules.Add(schedule1);

            Schedule schedule2 = new Schedule();
            schedule1.Name = "Schedule 2";
            schedule2.Duration = new Duration(new DateTime(), new DateTime());
            schedule2.MeetingRoomType = meetingRoomType2;
            schedules.Add(schedule2);

            this.getMeetingRoomByMeetingRoomTypeMockControl.ExpectAndReturn(
                "GetMeetingRoomByMeetingRoomType", meetingRooms1, meetingRoomType1);

            this.getMeetingRoomByMeetingRoomTypeMockControl.ExpectAndReturn(
                "GetMeetingRoomByMeetingRoomType", meetingRooms2, meetingRoomType2);

            this.getUpcomingSchedulesMockControl.ExpectAndReturn(
                "GetUpcomingSchedules", schedules, minutes);

            this.updateScheduleMockControl.ExpectAndReturn(
                "Update", true, schedule1);

            this.updateScheduleMockControl.ExpectAndReturn(
                "Update", true, schedule2);

            MeetingRoomAllocator meetingRoomAllocator = new MeetingRoomAllocator();
            meetingRoomAllocator.Minutes = minutes;
            meetingRoomAllocator.GetMeetingRoomsByMeetingRoomType 
                = this.getMeetingRoomByMeetingRoomTypeMock;
            meetingRoomAllocator.GetUpcomingSchedules = this.getUpcomingSchedulesMock;
            meetingRoomAllocator.MessagingService = this.messagingServiceMock;
            meetingRoomAllocator.UpdateSchedule = this.updateScheduleMock;

            int totalAllocated = meetingRoomAllocator.Allocate();

            Assert.AreEqual(2, totalAllocated);
            this.updateScheduleMockControl.Verify();
            this.getUpcomingSchedulesMockControl.Verify();
            this.getMeetingRoomByMeetingRoomTypeMockControl.Verify();
            this.messagingServiceMockControl.Verify();
        }
    }
}
